package com.shijie.component.tencent;

import com.qcloud.cos.COSClient;
import com.qcloud.cos.ClientConfig;
import com.qcloud.cos.auth.BasicCOSCredentials;
import com.qcloud.cos.auth.COSCredentials;
import com.qcloud.cos.model.ObjectMetadata;
import com.qcloud.cos.model.PutObjectResult;
import com.qcloud.cos.region.Region;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;


/**
 * 腾讯云cos工具上传图片
 * <p>
 * Created by yanqiu on 2018/7/31.
 */
@Component
public class TencentCloudCosClient {


    @Autowired
    TencentCloudCosConfig tencentCloudCosConfig;

    private COSClient client = null;


    @PostConstruct
    public COSClient init() {
        if (client != null) {
            return client;
        }
        // 1 初始化用户身份信息(secretId, secretKey)
        COSCredentials cred = new BasicCOSCredentials(tencentCloudCosConfig.getSecretId(), tencentCloudCosConfig.getSecretKey());
        // 2 设置bucket的区域, COS地域的简称请参照 https://cloud.tencent.com/document/product/436/6224
        ClientConfig clientConfig = new ClientConfig(new Region(tencentCloudCosConfig.getRegion()));
        // 3 生成cos客户端
        client = new COSClient(cred, clientConfig);
        return client;
    }


    /**
     * 上传到COS服务器 如果同名文件会覆盖服务器上的
     *
     * @param file 文件流
     * @return 出错返回"" ,唯一MD5数字签名
     */
    public String uploadFile2Cos(MultipartFile file) throws Exception {

        String url = new String();
        if (file.getSize() > 50 * 1024 * 1024) {
            throw new Exception("上传图片大小不能超过10M！");
        }
        String originalFilename = file.getOriginalFilename();

        String cosName = getPathUrl(originalFilename);
        if (StringUtils.isNotEmpty(cosName)) {
            url = getUrl(cosName);
        }
        try {
            InputStream inputStream = file.getInputStream();
            return this.upload(inputStream, originalFilename, cosName, url);
        } catch (Exception e) {
            throw new Exception("图片上传失败");
        }
    }

    /**
     * 上传到COS服务器 如果同名文件会覆盖服务器上的
     *
     * @param file 文件流
     * @return 出错返回"" ,唯一MD5数字签名
     */
    public String uploadFile2Cos(InputStream inputStream,String originalFilename) throws Exception {

        String url = new String();
        String cosName = getPathUrl(originalFilename);
        if (StringUtils.isNotEmpty(cosName)) {
            url = getUrl(cosName);
        }
        try {
            // 创建上传Object的Metadata
            return this.upload(inputStream, originalFilename, cosName, url);
        } catch (Exception e) {
            throw new Exception("图片上传失败");
        }
    }
    
    private String upload(InputStream inputStream,String originalFilename,String cosName,String url) throws Exception{
        // 创建上传Object的Metadata
        ObjectMetadata objectMetadata = new ObjectMetadata();
        objectMetadata.setContentLength(inputStream.available());
        objectMetadata.setCacheControl("no-cache");
        objectMetadata.setHeader("Pragma", "no-cache");
        objectMetadata.setContentType(getcontentType(originalFilename));
        objectMetadata.setContentDisposition("inline;filename=" + originalFilename);
        // 上传文件
        PutObjectResult putResult = client.putObject(tencentCloudCosConfig.getBucketName(), cosName, inputStream, objectMetadata);
        String ret = putResult.getETag();// 返回的MD5签名
        return url;
    }

    private String getPathUrl(String fileName) {
        // 设置URL过期时间为10年 3600l* 1000*24*365*10
        //Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);
        // 生成URL
        Date date = new Date();
        SimpleDateFormat sdf = new SimpleDateFormat();
        sdf.applyPattern("yyyyMMdd");

       /* URL url = client.generatePresignedUrl(tencentCloudCosConfig.getBucketName(), sdf.format(date) + '/' + fileName, expiration);
        if (url != null) {
            return url.toString();
        }
        return null;*/

        return sdf.format(date) + '/' + UUID.randomUUID().toString()+fileName;

    }

    /**
     * 获得url链接
     *
     * @param cosName
     * @return
     */
    private String getUrl(String cosName) {
        // 设置URL过期时间为10年 3600l* 1000*24*365*10
        Date expiration = new Date(System.currentTimeMillis() + 3600L * 1000 * 24 * 365 * 10);
        // 生成URL

        URL url = client.generatePresignedUrl(tencentCloudCosConfig.getBucketName(), cosName, expiration);
        if (url != null) {
            String strUrl = url.toString();
            // 域名替换为万象的
            return strUrl.substring(0, strUrl.indexOf("?")).replace(".cos.ap-shanghai.",".picsh.");

        }
        return null;


    }


    /**
     * Description: 判断Cos服务文件上传时文件的contentType
     *
     * @param filenameExtension 文件后缀
     * @return String
     */
    public static String getcontentType(String filenameExtension) {
        if (filenameExtension.toLowerCase().indexOf(".bmp") > 0) {
            return "image/bmp";
        }
        if (filenameExtension.toLowerCase().indexOf(".gif") > 0) {
            return "image/gif";
        }
        if (filenameExtension.toLowerCase().indexOf(".jpeg") > 0 || filenameExtension.indexOf(".jpg") > 0
                || filenameExtension.toLowerCase().indexOf(".png") > 0) {
            return "image/jpeg";
        }
        if (filenameExtension.toLowerCase().indexOf(".html") > 0) {
            return "text/html";
        }
        if (filenameExtension.toLowerCase().indexOf(".txt") > 0) {
            return "text/plain";
        }
        if (filenameExtension.toLowerCase().indexOf(".vsd") > 0) {
            return "application/vnd.visio";
        }
        if (filenameExtension.toLowerCase().indexOf(".pptx") > 0 || filenameExtension.toLowerCase().indexOf(".ppt") > 0) {
            return "application/vnd.ms-powerpoint";
        }
        if (filenameExtension.toLowerCase().indexOf(".docx") > 0 || filenameExtension.toLowerCase().indexOf(".doc") > 0) {
            return "application/msword";
        }
        if (filenameExtension.toLowerCase().indexOf(".xml") > 0) {
            return "text/xml";
        }
        return "image/jpeg";
    }


    @PreDestroy
    public void destroy() throws Exception {
        if (client != null) {
            client.shutdown();
        }
    }

}
